#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Finally 上下文栈管理

用于管理嵌套 try/finally 块的上下文信息
"""

from dataclasses import dataclass
from typing import Optional, List


@dataclass
class FinallyContext:
    """单个 finally 块的上下文信息"""

    label: str  # finally 标签名（如 __finally, __finally_2）
    suffix: str  # 变量名后缀（如 "", "_2"）
    return_type: Optional[str]  # 函数返回类型
    has_else: bool  # 是否有 else 块
    in_loop: bool  # 是否在循环中
    # 异步代码生成专用字段
    try_block_id: Optional[int] = None  # 异步代码生成使用的 try_block_id
    is_async: bool = False  # 是否为异步代码生成

    @property
    def exception_ptr_var(self) -> str:
        """异常指针变量名"""
        if self.is_async and self.try_block_id is not None:
            return f"__exception_ptr_try_{self.try_block_id}"
        return f"__exception_ptr{self.suffix}"

    @property
    def has_return_var(self) -> str:
        """是否有 return 的标志变量名"""
        if self.is_async and self.try_block_id is not None:
            return f"__has_return_try_{self.try_block_id}"
        return f"__has_return{self.suffix}"

    @property
    def return_value_var(self) -> str:
        """return 值变量名"""
        if self.is_async and self.try_block_id is not None:
            return f"__return_value_try_{self.try_block_id}"
        return f"__return_value{self.suffix}"

    @property
    def should_break_var(self) -> str:
        """是否需要 break 的标志变量名"""
        if self.is_async and self.try_block_id is not None:
            return f"__has_break_try_{self.try_block_id}"
        return f"__should_break{self.suffix}"

    @property
    def should_continue_var(self) -> str:
        """是否需要 continue 的标志变量名"""
        if self.is_async and self.try_block_id is not None:
            return f"__has_continue_try_{self.try_block_id}"
        return f"__should_continue{self.suffix}"

    @property
    def finally_label(self) -> str:
        """finally 标签名（用于 goto）"""
        if self.is_async and self.try_block_id is not None:
            return f"__try_{self.try_block_id}_finally"
        return self.label


class FinallyContextStack:
    """管理嵌套 finally 块的上下文栈"""

    def __init__(self):
        self._stack: List[FinallyContext] = []

    def push(self, context: FinallyContext):
        """进入 finally 块"""
        self._stack.append(context)

    def pop(self) -> FinallyContext:
        """退出 finally 块"""
        if not self._stack:
            raise RuntimeError("FinallyContextStack is empty, cannot pop")
        return self._stack.pop()

    def current(self) -> Optional[FinallyContext]:
        """获取当前 finally 上下文（栈顶）"""
        return self._stack[-1] if self._stack else None

    def outer(self) -> Optional[FinallyContext]:
        """获取外层 finally 上下文（相对于当前，即栈顶的下一层）"""
        return self._stack[-2] if len(self._stack) >= 2 else None

    def depth(self) -> int:
        """当前嵌套深度"""
        return len(self._stack)

    def is_empty(self) -> bool:
        """栈是否为空"""
        return len(self._stack) == 0

    def __repr__(self) -> str:
        """调试用的字符串表示"""
        if not self._stack:
            return "FinallyContextStack(empty)"
        contexts = ", ".join(f"{ctx.label}({ctx.suffix})" for ctx in self._stack)
        return f"FinallyContextStack(depth={self.depth()}, [{contexts}])"
